var update = (function () {
    // 获取元素
    function $ (selector) {
        return document.querySelector(selector)
    }

    // 传入元素参数赋值
    function Markdown (textarea, div, container) {
        this.textarea = textarea 
        this.div = div
        this.container = container
        this.timer = null
    } 
    
    // 向原型上赋方法
    Markdown.prototype = {
        // 初始化
        // 将 markdown 转换为 html
        init: function () {
            // oninput 用户输入时触发
            this.textarea.oninput = () => {
                this.div.innerHTML = this.compile(this.textarea.value)
            }
            
            this.container.onmouseenter = () => {
                if (this.timer) {
                    clearTimeout(this.timer)
                }
                this.timer = setTimeout(() => {
                    this.div.innerHTML = this.compile(this.textarea.value)
                }, 100)
            }
        },
        compile: function (initStr) {
            // 分割每一行
            var rows = initStr.split('\n')
            var matchArry
            // 存储返回的 html 
            var html = ''
            // 循环正则匹配每一行
            for (var i = 0, len = rows.length; i < len; i++) {
                // ^ 匹配字符串开始的位置
                // \s 匹配任何空白字符串，包括空格，制表符，换页符等等
                matchArry = rows[i].match(/^#{1}\s/)
                         || rows[i].match(/^#{2}\s/)
                         || rows[i].match(/^#{3}\s/)
                         || rows[i].match(/^#{4}\s/)
                         || rows[i].match(/^#{5}\s/)
                         || rows[i].match(/^#{6}\s/)
                         // \* 匹配 *
                         // {n,} 匹配至少出现 3 次
                         || rows[i].match(/^\*{3,}/)
                         || rows[i].match(/^\-{3,}/)
                         || rows[i].match(/^>\s/)
                        //  || rows[i].match(/^\*\s/)
                        //  || rows[i].match(/^\d\.\s/)
                         || rows[i].match(/^```$/)
                        //  || rows[i].match(/^\|.*\|/)
                if (matchArry) {
                    switch(matchArry[0]) {
                        // substring(n) 取出字符串中 n 个字符以后组成新的字符串
                        case '# ':
                            html += '<h1>' + this.format(rows[i].substring(2)) + '</h1>';
                            break;
                        case '## ':
                            html += '<h2>' + this.format(rows[i].substring(3)) + '</h2>';
                            break;
                        case '### ':
                            html += '<h3>' + this.format(rows[i].substring(4)) + '</h3>';
                            break;
                        case '#### ':
                            html += '<h4>' + this.format(rows[i].substring(5)) + '</h4>';
                            break;
                        case '##### ':
                            html += '<h5>' + this.format(rows[i].substring(6)) + '</h5>';
                            break;
                        case '###### ':
                            html += '<h6>' + this.format(rows[i].substring(7)) + '</h6>';
                            break;
                        case rows[i].match(/^\*{3,}/) && rows[i].match(/^\*{3,}/)[0]:
                            html += rows[i].replace(/^\*{3,}/g, '<hr class="bar">');
                            break;
                        case '---':
                            html += rows[i].replace(/^\-{3,}/g, '<hr class="bar">');
                            break;
                        case '> ':
                            var temp = '';
                            var re = /^>\s/;
                            while (i < len && rows[i].match(re)) {
                                temp += '<p><xmp>' + rows[i].substring(2, rows[i].length) + '</xmp></p>';
                                i++;
                            }
                            html += '<div class="quote"><div class="prefix"></div>' + temp + '</div>';
                            break;
                        case '```':
                            var temp = '';
                            var re = /^```$/;
                            i++;
                            while (i < len && !re.test(rows[i])) {
                                temp += rows[i] + '\n';
                                i++;
                            }
                            // html += '<div class="multi"><pre>' + temp + '</pre></div>';
                            html += '<xmp class="multi">' + temp + '</xmp>'
                            break;
                        default:
                            break;
                        } 
                    } else {
                        html += '<p>' + this.format(rows[i]) + '<p>'
                    }
            }
            // 返回 markdown 转换之后的 html 文件
            return html
        },
        // 处理行内 markdown 语法
        format: function (str) {
            // 转换空格
            str = str.replace(/\s/g, '&nbsp;')
         
            // 匹配加粗内容
            var bold = str.match(/\*{2}[^*].*?\*{2}/g);
            if (bold) {
                for (var i = 0, len = bold.length; i < len; i++) {
                    // 对 str 中需要加粗的内容用 html 进行替换
                    str = str.replace(bold[i], '<b>' + bold[i].substring(2, bold[i].length - 2) + '</b>')
                }
            }

            // 匹配斜体内容
            var italic = str.match(/\*[^*].*?\*/g);
            if (italic) {
                for (var i = 0, len = italic.length; i < len; i++) {
                    // 对 str 中需要斜体的内容用 html 进行替换
                    str = str.replace(italic[i], '<i>'+ italic[i].substring(1, italic[i].length - 1) +'</i>')
                }
            }

            // 匹配删除内容
            var strike = str.match(/\~{2}[^*].*?\~{2}/g);
            if (strike) {
                for (var i = 0, len = strike.length; i < len; i++) {
                    str = str.replace(strike[i], '<s>' + strike[i].substring(2, strike[i].length - 2) + '</s>')
                }
            }

            // 匹配单行代码
            var code = str.match(/`.+`/g);
            if (code) {
                for (var i = 0, len = code.length; i < len; i++) {
                    // 对 str 中单行代码的内容用 html 进行替换
                    let short = '<div class="single"><xmp>' + code[i].substring(1, code[i].length - 1) + '</xmp></div>'
                    str = str.replace(code[i], short)
                }
            }

            return str
        }       
    }

    // 实例化对象，并传入参数初始化
    new Markdown($('textarea'), $('.right_div'), $('#container')).init()
// 自执行函数，引入便执行
})() 
